import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

public class Main {

    //保存文件名
    static String saveDataName="save.txt";

    //主
    static JFrame jFrame=new JFrame("adb自动安装apk文件");

    //文字和输入框
    static JTextArea jTextAreaDrive=new JTextArea();
    static JTextArea jTextAreaFile=new JTextArea();
    static JLabel jLabelDrive=new JLabel();
    static JLabel jLabelFile=new JLabel();

    //提示文本
    static  JTextArea jTextAreaTip=new JTextArea();

    //按钮
    static JButton jButton=new JButton("安装到手机");

    public static void main(String[] args) {
        // 初始化数据
        init();

        // 查找并安装APK文件
        //findAndInstallApks();
    }
    //读取数据方法
    public static void loadData(){
        //尝试打开
        File file=new File(saveDataName);
        if(file.exists()){
            //读取文件
            try {
                BufferedReader bw=new BufferedReader(new FileReader(file));
                String s = bw.readLine();
                if (s.contains("@")){
                    System.out.println(s);
                    PublicData.drive=s.split("@")[0];
                    PublicData.installFile=s.split("@")[1];
                    jTextAreaDrive.setText(PublicData.drive);
                    jTextAreaFile.setText(PublicData.installFile);
                }
             } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }else {
            //如果没有文件
            //创建文件
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
            PublicData.drive = "E";
            PublicData.installFile = "InstallApp";
        }
    }

    // 初始化方法
    private static void init() {
        // 初始化数据
        loadData();

        // 获取屏幕尺寸
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

        // 计算JFrame的位置使其居中
        int x = (screenSize.width - 400) / 2;
        int y = (screenSize.height - 400) / 2;

        // 设置JFrame的位置和大小  (屏幕中间)
        jFrame.setBounds(x, y, 400, 400);
        jFrame.setLayout(null);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        jTextAreaDrive.setBounds(120, 10, 220, 30);
        jTextAreaFile.setBounds(120, 50, 220, 30);
        jLabelDrive.setBounds(40, 10, 80, 30);
        jLabelDrive.setText("输入盘符");
        jLabelFile.setBounds(40, 50, 80, 30);
        jLabelFile.setText("输入文件名");
        jTextAreaTip.setBounds(40,150,300,200);
        jTextAreaTip.setEnabled(false);
        jTextAreaTip.setDisabledTextColor(Color.BLACK);
        jButton.setBounds(100, 100, 200, 30);
        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                // 获取输入框的值
                String drive = jTextAreaDrive.getText();
                String file = jTextAreaFile.getText();
                //保存文件到公共数据
                PublicData.drive = drive;
                PublicData.installFile = file;
                //保存文件到本地
                saveData();
                //清空提示文本
                jTextAreaTip.setText("");

                if (!isDeviceConnected()){
                    System.out.println("没有设备连接");
                    showWarningAlert("没有设备连接");
                    return;
                }

                //执行安装
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        findAndInstallApks();
                    }
                }).start();
            }
        });

        jFrame.add(jTextAreaDrive);
        jFrame.add(jTextAreaFile);
        jFrame.add(jLabelDrive);
        jFrame.add(jLabelFile);
        jFrame.add(jTextAreaTip);
        jFrame.add(jButton);

        jFrame.setVisible(true);
    }

    //保存文件方法
    private static void saveData() {
        System.out.println("保存数据");
        File file=new File(saveDataName);
        //将公共数据文件写入
        try (FileWriter fileWriter = new FileWriter(file)) {
            fileWriter.write(PublicData.drive + "@" + PublicData.installFile);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    // 递归查找路径下所有.apk文件并安装
    private static void findAndInstallApks() {
        //状态:正在安装
        PublicData.isInstall=true;
        jButton.setEnabled(false);

        //按钮的显示
        new Thread(new Runnable() {
            @Override
            public void run() {
                int i=0;
                while (PublicData.isInstall){
                    jButton.setText(PublicData.installStr[i]);
                    i++;
                    i%=PublicData.installStr.length;
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                //到这里说明安装完成
                jButton.setText("安装到手机");
                System.out.println("全部安装完成");
                showWarningAlert("全部安装完成!");
                jButton.setEnabled(true);
            }
        }).start();

        Path basePath = Paths.get(PublicData.drive + ":\\" + PublicData.installFile);

        try (Stream<Path> paths = Files.walk(basePath)) {
            paths
                    .filter(Files::isRegularFile) // 过滤掉非文件（即目录）
                    .filter(path -> path.toString().endsWith(".apk")) // 过滤出.apk文件
                    .forEach(Main::installApk); // 调用installApk方法安装每个.apk文件
            //到这里说明安装完成
            PublicData.isInstall=false;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 安装方法, 使用adb命令安装APK到手机上
    private static void installApk(Path apkPath) {
        // 构造adb install命令
        String command = "adb install " + apkPath.toString();
        System.out.println("正在安装:"+apkPath.toString());

        //设置提示文本
        new Thread(new Runnable() {
            @Override
            public void run() {
                jTextAreaTip.setText(
                        jTextAreaTip.getText()+
                        "正在安装   -->   "+apkPath.toString()+"\n");
            }
        }).start();

        try {
            // 执行命令
            Process process = Runtime.getRuntime().exec(command);

            // 读取命令输出（如果需要的话）
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                if ("Success".equals(line)){
                    System.out.println("安装成功");
                    //更新文本
                    String text = jTextAreaTip.getText();
                    String newStr = text.replace("正在安装", "安装完成");
                    jTextAreaTip.setText(newStr);
                }
            }

            // 等待命令执行完成
            int exitCode = process.waitFor();
            //System.out.println("\n退出代码为 : " + exitCode);

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    //是否有设备连接方法
    public static boolean isDeviceConnected() {
        try {
            // 执行 adb devices 命令
            Process process = Runtime.getRuntime().exec("adb devices");

            // 读取命令的输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            boolean foundDevice = false;

            // 跳过第一行（通常是 List of devices attached:）
            reader.readLine();

            // 读取并检查每一行输出
            while ((line = reader.readLine()) != null) {
                // 如果行以 "device" 结尾，说明找到了一个已连接的设备
                if (line.trim().endsWith("device")) {
                    foundDevice = true;
                    break; // 找到设备后，可以退出循环
                }
            }

            // 关闭读取器
            reader.close();

            // 等待命令执行完成
            int exitCode = process.waitFor();

            // 检查命令是否成功执行（通常，0 表示成功）
            if (exitCode != 0) {
                System.err.println("ADB command failed with exit code " + exitCode);
                return false;
            }

            // 返回是否找到设备
            return foundDevice;

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
            return false;
        }
    }

    //警告框方法
    public static void showWarningAlert(String message) {
        // 使用JOptionPane显示模态警告框
        JOptionPane.showMessageDialog(null, message, "警告", JOptionPane.WARNING_MESSAGE);
    }
}